package me.zhengjie.modules.weixin.service.impl;

import com.alibaba.excel.util.DateUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.vioao.wechat.api.UserApi;
import com.github.vioao.wechat.bean.response.user.UserResponse;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.bean.subscribe.WxMpSubscribeMessage;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import me.zhengjie.config.constant.WeChatConstant;
import me.zhengjie.constant.ConstantUtils;
import me.zhengjie.enums.WechatTemplateIdEnums;
import me.zhengjie.modules.system.domain.CourseInfo;
import me.zhengjie.modules.system.domain.WxUser;
import me.zhengjie.modules.system.domain.WxUserRecommand;
import me.zhengjie.modules.system.service.DictDetailService;
import me.zhengjie.modules.system.service.WxUserRecommandService;
import me.zhengjie.modules.system.service.WxUserService;
import me.zhengjie.modules.web.domain.config.RichTextResp;
import me.zhengjie.modules.web.service.config.IConfigService;
import me.zhengjie.modules.web.service.mybatisplus.ICourseInfoPlusService;
import me.zhengjie.modules.weixin.enums.WeChatEventEnum;
import me.zhengjie.modules.weixin.service.IWechatEventService;
import me.zhengjie.modules.weixin.utils.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.sql.Timestamp;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.util.*;

@Service
public class WechatEventServiceImpl implements IWechatEventService {
    private static final Logger log = LoggerFactory.getLogger(WechatEventServiceImpl.class);

    @Autowired
    private WxMpService wxMpService;

    @Autowired
    private WxUserRecommandService recommandService;

    @Autowired
    private WxUserService wxUserService;

    @Autowired
    private DictDetailService dictDetailService;

    @Autowired
    private ICourseInfoPlusService courseInfoPlusService;

    @Value("${qrcode.signInUrl}")
    String signInUrl;

    @Autowired
    private IConfigService configService;


    @Override
    public String process(Map<String,String> map) {
        // 事件KEY值
        String eventKey = map.get("EventKey");
        String qrScene = eventKey.replace("qrscene_", "");
        // 消息类型
        String msgType = map.get("MsgType");
        // 事件类型
        String eventType = map.get("Event");

        String openId = map.get("FromUserName");
        WxUser wxUser = wxUserService.findByOpenId(openId);
        WeChatEventEnum eventEnum = WeChatEventEnum.get(eventType);

        log.info("msgType:"+msgType+",eventKey="+eventKey+",qrScene="+qrScene+",eventType="+eventType+",openId="+openId+",wxUser="+ JSON.toJSONString(wxUser));
        // 有特殊逻辑，可以针对不同事件分别处理，方便后续改为消息走数据库配置
        switch (eventEnum) {
            case subscribe:
                //自动回复欢迎词
                autoReplyContent(openId);
                //autoReplyContentRichText(openId);
                log.info("关注事件:"+openId);
                String superior = "";
                if (StringUtils.isNotBlank(qrScene) && qrScene.startsWith("ATMR_")) {
                    //当作推荐过来的 qrscene结果 openId
                    qrScene = qrScene.replace(WeChatConstant.QrCodeScenePrefix,"");
                    superior = qrScene;
                    WxUserRecommand one = recommandService.findOne(qrScene, openId);
                    if (null == one){
                        log.info("推荐表中不存在数据插入");
                        UserResponse wxMpUser = getWxUser(openId);
                        WxUserRecommand wxUserRecommand = new WxUserRecommand();
                        wxUserRecommand.setOpenId(qrScene);
                        wxUserRecommand.setObjOpenid(openId);
                        wxUserRecommand.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
                        wxUserRecommand.setNickName("");
                        wxUserRecommand.setHeadPic("");
                        if (null != wxMpUser){
                            wxUserRecommand.setNickName(wxMpUser.getNickname());
                            wxUserRecommand.setHeadPic(wxMpUser.getHeadimgurl());
                        }
                        try {
                            recommandService.create(wxUserRecommand);
                            log.info("推荐表中插入成功");
                        } catch (Exception e) {
                            log.info("推荐表中插入数据失败");
                        }
                    }
                }
                if (null != wxUser){
                    log.info("更新关注时间");
                    wxUser.setSubscribeTime(DateUtil.date2String(new Date()));
                    wxUser.setSubscribe(Boolean.TRUE.toString());
                    wxUserService.update(wxUser);
                }else {
                    log.info("关注插入用户表");
                    WxUser user = new WxUser();
                    UserResponse wxMpUser = getWxUser(openId);
                    if (null != wxMpUser){
                        log.info("关注的用户信息："+JSON.toJSONString(wxMpUser));
                        user.setNickname(wxMpUser.getNickname());
                        user.setHeadimgurl(wxMpUser.getHeadimgurl());
                        user.setProvince(wxMpUser.getProvince());
                        user.setCity(wxMpUser.getCity());
                        user.setSex(String.valueOf(wxMpUser.getSex()));
                        user.setCountry(wxMpUser.getCountry());
                        user.setGroupid(String.valueOf(wxMpUser.getGroupid()));
                        user.setLanguage(wxMpUser.getLanguage());
                        user.setSubscribe(Boolean.TRUE.toString());
                        user.setSubscribeTime(DateUtil.date2String(new Date()));
                        user.setOpenId(openId);
                        user.setSuperior(superior);
                        if (StringUtils.isNotBlank(superior)){
                            WxUser superiorUser = wxUserService.findByOpenId(superior);
                            if (Objects.nonNull(superiorUser)){
                                user.setSuperiorMobile(superiorUser.getMobile());
                                user.setSuperiorNickName(superiorUser.getNickname());
                                user.setSuperiorRealName(superiorUser.getRealName());
                            }
                        }
                        wxUserService.create(user);
                    }
                }
                break;
            case unsubscribe:
                log.info("取消关注事件");
                if (null != wxUser){
                    wxUser.setSubscribe(Boolean.FALSE.toString());
                    wxUserService.update(wxUser);
                }
                break;
            case VIEW:
                break;
            case view_miniprogram:
                break;
            case CLICK:
                if (StringUtils.isNotBlank(eventKey)) {
                }
                break;
            case LOCATION:
                break;
            case SCAN:
                if (StringUtils.isNotBlank(qrScene)) {

                }
                break;
            case user_get_card:
                break;
            case pic_photo_or_album:
            case pic_weixin:
            case pic_sysphoto:
                break;
            default:
                break;
        }
        return "";
    }

    private void autoReplyContent(String openId) {
        WxMpKefuMessage mpKefuMessage = new WxMpKefuMessage();
        mpKefuMessage.setToUser(openId);
        mpKefuMessage.setContent(getFollowReplyContent());
        mpKefuMessage.setMsgType(WxConsts.KefuMsgType.TEXT);
        try {
            wxMpService.getKefuService().sendKefuMessage(mpKefuMessage);
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
    }

    private void autoReplyContentRichText(String openId) {
        WxMpKefuMessage mpKefuMessage = new WxMpKefuMessage();
        mpKefuMessage.setToUser(openId);
        mpKefuMessage.setContent(getFollowReplyContentRichText());
        mpKefuMessage.setMsgType(WxConsts.KefuMsgType.TEXT);
        try {
            wxMpService.getKefuService().sendKefuMessage(mpKefuMessage);
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
    }

    private void templateMessage(String openId) {
        CourseInfo lastCourseInfo = getLastCourseInfo();
        if (Objects.isNull(lastCourseInfo)){
            return;
        }
        String url = MessageFormat.format(signInUrl,lastCourseInfo.getCourseNo());
        WxMpTemplateMessage wxMpTemplateMessage = new WxMpTemplateMessage();
        wxMpTemplateMessage.setTemplateId(WechatTemplateIdEnums.SignInReminder.getTemplateId());
        wxMpTemplateMessage.setToUser(openId);
        wxMpTemplateMessage.setUrl(url);
        List<WxMpTemplateData> dataList = new ArrayList<>();

        WxMpTemplateData dataVar1 = new WxMpTemplateData();
        dataVar1.setName("time8");
        dataVar1.setValue(DateUtils.format(new Date()));
        dataList.add(dataVar1);

        WxMpTemplateData dataVar2 = new WxMpTemplateData();
        dataVar2.setName("thing7");
        dataVar2.setValue(lastCourseInfo.getCourseLocation());
        dataList.add(dataVar2);

        WxMpTemplateData dataVar3 = new WxMpTemplateData();
        dataVar3.setName("thing13");
        dataVar3.setValue(lastCourseInfo.getCourseName());
        dataList.add(dataVar3);

        wxMpTemplateMessage.setData(dataList);
        try {
            wxMpService.getTemplateMsgService().sendTemplateMsg(wxMpTemplateMessage);
        } catch (WxErrorException e) {
            log.error("公众号推送异常",e);
        }
    }

    private UserResponse  getWxUser(String openId){
        try {
            log.info("getAccessToken===="+wxMpService.getAccessToken());
            UserResponse userInfo = UserApi.getUserInfo(wxMpService.getAccessToken(), openId);
            if (null != userInfo){
                log.info("userInfo===="+JSON.toJSONString(userInfo));
                return userInfo;
            }
        } catch (WxErrorException e) {
            log.error("getUserInfo is error",e);
        }
        WxMpUser wxMpUser = null;
        try {
            wxMpUser = wxMpService.getUserService().userInfo(openId);
        } catch (WxErrorException e) {
            log.error("userInfo is error",e);
        }
        if (wxMpUser != null){
            UserResponse response = new UserResponse();
            response.setNickname(wxMpUser.getNickname());
            response.setHeadimgurl(wxMpUser.getHeadImgUrl());
            response.setSex(0);
            return response;
        }
        return null;
    }

    private String getFollowReplyContent(){
        String dictValueByLable = dictDetailService.getDictValueByLable("wx_mp_config", "FollowAutoReply");
        if (StringUtils.isBlank(dictValueByLable)){
            return "欢迎关注ATMR慧识人平台！！";
        }
        return dictValueByLable;
    }
    private String getFollowReplyContentRichText(){
        RichTextResp richTextResp = configService.getRichTextByType("richtext_type_mp_follow_autoreplay");
        if (Objects.isNull(richTextResp) || StringUtils.isBlank(richTextResp.getContent())){
            return "欢迎关注ATMR慧识人平台！！";
        }
        return richTextResp.getContent();
    }

    private CourseInfo getLastCourseInfo(){
        LambdaQueryWrapper<CourseInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CourseInfo::getStatus, ConstantUtils.Valid).eq(CourseInfo::getOpenTime, DateUtil.getCurrentDate());
        queryWrapper.orderByDesc(CourseInfo::getCreateTime);
        List<CourseInfo> courseInfoList = courseInfoPlusService.list(queryWrapper);
        if (CollectionUtils.isEmpty(courseInfoList)){
            return null;
        }
        return courseInfoList.get(0);
    }
}
